package modelo;

import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.awt.Component;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import vista.VentanaCalendario;
import controlador.ControladorVentanaCalendario;
import controlador.ControladorVentanaPlayoff;

public class Liga {

		private ArrayList<Umpire> umpires;
		private ArrayList<Equipo> equipos;
		private ArrayList<Partido> partidos;
		private ArrayList<Partido> juganotpart;
		private ControladorVentanaPlayoff controladorVentanaPlayoff;
		
		Calendar c1;
		Calendar c2;
		int j, home, visit, jjHome, jjVisit, carrHome, carrVisit, cuadHome, cuadVisit, inn, ump, longCodPart, lunesAcum = 0;
		String eHome, eVisit, umpCedula, codPart;
		boolean valido = true;
		SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
		
		//PATRON SINGLETON
		private static Liga instancia;
		
		public static Liga getInstancia() {
			if (instancia == null)
				instancia = new Liga();
			return instancia;
		}

		public Liga() {
			this.umpires = new ArrayList<Umpire>();
			this.equipos = new ArrayList<Equipo>();
			this.partidos = new ArrayList<Partido>();
			this.juganotpart = new ArrayList<Partido>();
		}
		
		// cuenta las carreras impulsadas por cada jugador en cada partido 
		/*public int contarCarrPart(String cedula){
			int contar=0;
			for (int i=0; i<this.contarAnotaciones(); i++){
				juganotpart.get(i).
			}
		return contar;	
		}*/
		
		//registra un umpire
		public void registrarUmpire(Umpire umpire) {
			this.umpires.add(umpire);
		}

		//registra un equipo a la liga
		public void registrarEquipo(Equipo equipo) {
			this.equipos.add(equipo);
		}
		
		//registra un partido realizado a la liga
		public void registrarPartido(Partido partido) {
			this.partidos.add(partido);
		}
		
		//registra al jugador que anoto carreras y/o cuadrangulares
		public void regjugAnotador(Partido japartido) {
			this.juganotpart.add(japartido);
		}
		
		//contar umpires registrados
		public int contarUmpires() {
			return this.umpires.size();
		}
		
		//contar equipos registrados
		public int contarEquipos() {
			return this.equipos.size();
		}
		
		//contar partidos realizados
		public int partidosRealizados() {
			return this.partidos.size();
			
		}
		
		//contar anotaciones
		public int contarAnotaciones() {
			return this.juganotpart.size();
		}
		
		public ArrayList<Umpire> getUmpires(){
			if (this.contarUmpires() > 0) {
				return this.umpires;
			}
			else 
				return null;
		}

		public ArrayList<Equipo> getEquipos(){
			if (this.contarEquipos() > 0) {
				return this.equipos;
			}
			else 
				return null;
		}
		
		public ArrayList<Partido> getPartidos(){
			if (this.partidosRealizados() > 0) {
				return this.partidos;
			}
			else 
				return null;
		}
		
		public ArrayList<Partido> getJugAnotPart(){
			if (this.contarAnotaciones() > 0) {
				return this.juganotpart;
			}
			else
				return null;
		}
		
		// Equipo primer lugar -------------------------------------------------
		public Equipo primerEquipo(){
			Equipo equipo = equipos.get(0);
			int mayor = equipo.getjGanados();
			for (int i=1; i < equipos.size(); i++){
				if (mayor < equipos.get(i).getjGanados()){
					mayor = equipos.get(i).getjGanados();
					equipo = equipos.get(i);
				}
			}
			return equipo;
		}
				
		// Ordenar equipos -----------------------------------------------------
				
		public void ordenarEquipos(){			
			class comparadorDif implements Comparator<Equipo>{
				@Override
				public int compare(Equipo e1, Equipo e2) {
					return new Double(e1.Diferencia(primerEquipo())).compareTo(e2.Diferencia(primerEquipo()));
				}
			}
			Collections.sort(equipos, new comparadorDif());
		}	
			
		// Fecha del partido --------------------------------------------------
			public void FechaPartido(int jornada){
			c1 = Calendar.getInstance();
			c2 = Calendar.getInstance();
			c2.set(Calendar.DAY_OF_YEAR,c1.get(Calendar.DAY_OF_YEAR)+jornada+6+lunesAcum);		
			if(c2.get(Calendar.DAY_OF_WEEK)==2){
				lunesAcum++;
			}
			c1.add(Calendar.DATE, jornada+6+lunesAcum);
			}
			
		// Seleccion de equipos a jugar (indice) ------------------------------
			public void elegirEquipos(int jornada){
				do{
					home = (int) Math.floor(Math.random() * this.equipos.size());
					visit = (int) Math.floor(Math.random() * this.equipos.size());
					jjHome = this.equipos.get(home).getjJugados();
					jjVisit = this.equipos.get(visit).getjJugados();
				} while ((visit == home) || (jjHome != jjVisit) || (jjHome == jornada));
				equipos.get(home).setjJugados(j);
				equipos.get(visit).setjJugados(j);
			}
			
		// Marcador del juego -------------------------------------------------
			public void marcadorJuego(){
			inn = 8;
				do{
					carrHome = (int)Math.floor(Math.random() * 16);
					carrVisit = (int) Math.floor((Math.random() * 16));
					inn ++;
				} while (carrHome == carrVisit);
			
				do{
					cuadHome = (int) Math.floor(Math.random() * 3);
					cuadVisit = (int) Math.floor(Math.random() * (3 - cuadHome));
				} while (carrHome < cuadHome || carrVisit < cuadVisit);		
				
				//Suma de jj, jg, jp
						eHome = this.equipos.get(home).getNombre();
						eVisit = this.equipos.get(visit).getNombre();
						
					if (carrHome>carrVisit){
						equipos.get(home).setjGanados((equipos.get(home).getjGanados())+1);
						equipos.get(visit).setjPerdidos((equipos.get(visit).getjPerdidos())+1);
					}else{
						equipos.get(visit).setjGanados((equipos.get(visit).getjGanados())+1);
						equipos.get(home).setjPerdidos((equipos.get(home).getjPerdidos())+1);
						}

			// Jugadores que hacen las carreras
				int carrjug = 0;
				for(int j=0; j<carrHome;j++){
					int iJug = (int) Math.floor(Math.random() * equipos.get(home).getJugadores().size());
					String cedjug = equipos.get(home).getJugadores().get(iJug).getCedula();
					String nombjug = equipos.get(home).getJugadores().get(iJug).getNombre();
					String apejug = equipos.get(home).getJugadores().get(iJug).getApellido();
					if (juganotpart.size()>0){
						for(int l=0; l<juganotpart.size();l++){
							if(codPart==juganotpart.get(l).getCodigo() && cedjug==juganotpart.get(l).getCedjugAnot()){
								carrjug=juganotpart.get(l).getCarrJug()+1;
								juganotpart.get(l).setCarrJug(carrjug);
								l=juganotpart.size();
							} else carrjug=1;
						}
					}else carrjug=1;
					
					if(carrjug==1){
					Partido jugAnotPart = new Partido(codPart, 'H', eHome, cedjug, nombjug, apejug, carrjug, 0);
					this.regjugAnotador(jugAnotPart);}
				}
				for(int j=0; j<carrVisit;j++){
					int iJug = (int) Math.floor(Math.random() * equipos.get(visit).getJugadores().size());
					String cedjug = equipos.get(visit).getJugadores().get(iJug).getCedula();
					String nombjug = equipos.get(visit).getJugadores().get(iJug).getNombre();
					String apejug = equipos.get(visit).getJugadores().get(iJug).getApellido();
					if (juganotpart.size()>0){
						for(int l=0; l<juganotpart.size();l++){
							if(codPart==juganotpart.get(l).getCodigo() && cedjug==juganotpart.get(l).getCedjugAnot()){
								carrjug=juganotpart.get(l).getCarrJug()+1;
								juganotpart.get(l).setCarrJug(carrjug);
								l=juganotpart.size();
							} else carrjug=1;
						}
					}else carrjug=1;
					
					if(carrjug==1){
					Partido jugAnotPart = new Partido(codPart, 'V', eVisit, cedjug, nombjug, apejug, carrjug, 0);
					this.regjugAnotador(jugAnotPart);}
				}
				
			//Jugadores que hacen cuadrangulares
				for(int j=0; j<cuadHome;j++){
					int iJug;
					do{
						iJug = (int) Math.floor(Math.random() * juganotpart.size());
					} while ((codPart!=juganotpart.get(iJug).getCodigo()) || (eHome!=juganotpart.get(iJug).getEjugAnot()));
					juganotpart.get(iJug).setCuadJug(juganotpart.get(iJug).getCuadJug()+1);
				}
				for(int j=0; j<cuadVisit;j++){
					int iJug;
					do{
						iJug = (int) Math.floor(Math.random() * juganotpart.size());
					} while ((codPart!=juganotpart.get(iJug).getCodigo()) || (eVisit!=juganotpart.get(iJug).getEjugAnot()));
					juganotpart.get(iJug).setCuadJug(juganotpart.get(iJug).getCuadJug()+1);
				}
			}
			
		// Seleccion de umpire --------------------------------------------------
			public void elegirUmpire(int jornada){
				do{
					valido = true;
					ump = (int) Math.floor(Math.random() * this.umpires.size());
					umpCedula = umpires.get(ump).getCedula();
						for(int l=0; l < partidosRealizados(); l++){
							longCodPart = partidos.get(l).getCodigo().length();
							String codPart = partidos.get(l).getCodigo();
							int jActual = jornada;
							int jPartido = Integer.valueOf(codPart.substring(2, longCodPart-2));
								if((jActual == jPartido) && (umpCedula==partidos.get(l).getUmpire())){
									valido = false;
								}
						}
				}while (valido == false);
			umpires.get(ump).setjArbitrados(umpires.get(ump).getjArbitrados()+1);
			}
			
		// Calendario ---------------------------------------------------------
			public void CrearCalendario() {
						
					for (j=1; j <= (this.equipos.size()-1)*4; j++){
						FechaPartido(j);					
						for (int k=1; k <= this.equipos.size()/2; k++){
							codPart="J-"+j+"P"+k;
							elegirEquipos(j);
							elegirUmpire(j);
							marcadorJuego();
							// Registrar partido
							Partido partido = new Partido(codPart,formato.format(c1.getTime()),eHome,eVisit,
									umpCedula,inn,carrHome,carrVisit,cuadHome,cuadVisit);
							this.registrarPartido(partido);
						}
					}
					ordenarEquipos();
			}
						
		}
			
